<template>
    <div ref="chart" :style="{ width: width, height: height }" class="pie-chart"></div>
  </template>
  
  <script>
  import * as echarts from 'echarts'
import resize from '../resize'
  
  require('echarts/theme/macarons')
  
  export default {
    name: 'PieChart',
    mixins: [resize],
    props: {
      // chartDOM宽度
      width: {
        type: String,
        default: '100%',
      },
      // chartDOM高度
      height: {
        type: String,
        default: '320px',
      },
      // 配置
      // 该参数用于跟默认配置做递归树合并，得到新的默认配置
      option: {
        type: Object,
        default: function () {
          return {}
        },
      },
      seriesData: {
        // 需要显示的数据
        type: Array,
        default: function () {
          return []
        },
      },
      monitor: {
        type: Boolean,
        default: false,
      },
    },
    data() {
      return {
        chart: null, // chart实例
        // 默认serie配置
        defSerie: {
          // barMinWidth: 8,
          // barMaxWidth: 32,
          data: [],
          itemStyle: {
            // normal: {
            // barBorderRadius: 16,
            // shadowColor: '#eeeeee',
            // shadowBlur: 1,
            // },
          },
          // 文本标签
          label: {
            // normal: {
            show: false,
            // 文本内容格式化
            //     可以是模板字符串{'{a}': 系列名, '{b}': 数据名, '{c}': 数据值, {d}': 百分比}
            //     可以是function
            //         {<text_mapContent>|<text_content>}
            //         上面的写法，可以配合rich做到更深的自定义，左边的字符串映射右边的文本内容
            formatter: function (params) {
              return `{x${params.dataIndex}|${params.percent}%}`
              // },
              // 富文本样式
              //     接收一个Object，可以用function返回，但经过测试，function不能写在这里，得写在外面
            },
          },
          minAngle: 10, // 最小圆心角度
          name: '',
          roseType: false, // 是否南丁格尔图{true: 默认圆心角不等, 'radius': 默认圆心角不等, 'area': 默认圆心角相等}
          type: 'pie',
        },
      }
    },
    computed: {
      comp_option() {
        let obj = {
          backgroundColor: '#ffffff',
          color: ['#FFDCDF', '#FFBCC2', '#FFA7AF', '#FF7F8A', '#FF4A5A', '#EB0A1E'],
          grid: {
            top: 40,
            bottom: 64,
          },
          // 图例
          legend: {
            bottom: 5,
            icon: 'circle', // 图例形状{'roundRect': 默认圆角矩形, 'circle': 圆形}
            itemHeight: 16, // 图例高
            itemWidth: 16, // 图例宽
            // 图例文本样式
            textStyle: {
              fontSize: 14,
            },
            type: 'plain', // 类型{'plain': 普通, 'scroll': 可滚动}
          },
          // 图形系列数据
          series: [
            // 测试用的数据 start --------------------
            {
              id: 'series0',
              type:'pie',
              data: [
                // { name: '房产类', value: 622 },
                // { name: '土地使用权类', value: 2271 },
                // { name: '在建工程类', value: 3622 },
                // { name: '生产设备类', value: 388 },
                // { name: '广告位类', value: 421 },
                // { name: '其它类', value: 69 },
              ],
              // name: 'series0_name',
            },
            // 测试用的数据 end --------------------
          ],
          // 悬浮文本框
          tooltip: { trigger: 'item' },
        }
  
        this.mergeOption(obj, this.option)
  
        return obj
      },
    },
    watch: {
      seriesData: {
        deep: true,
        handler(val) {
          this.init()
          this.setOption(val)
        },
      },
    },
    mounted() {
      this.chart = echarts.init(this.$refs.chart)
      this.init()
      this.setOption(this.seriesData)
      if (this.monitor) {
        this.chart.on('click', params => {
          this.$emit('clicked', params)
        })
      }
    },
    beforeDestroy() {
      if (!this.chart) {
        return
      }
      this.chart.dispose()
      this.chart = null
    },
    methods: {
      /**
       * @description: 初始化
       * @param {Funtion} beforeFn 初始化前的函数
       */
      init(beforeFn = function () {}) {
        let finalOption = beforeFn.call(this, JSON.parse(JSON.stringify(this.comp_option)), { ...this.defSerie }) || this.comp_option
  
        this.chart.setOption(finalOption, true)
      },
      setOption(data) {
        if (!data) return
        this.chart.setOption({
          series: data,
        })
      },
      /**
       * @description: 合并配置
       * @param {*} defOption 默认配置
       * @param {*} newOption 新配置
       */
      mergeOption(defOption, newOption) {
        for (const [k, v] of Object.entries(newOption)) {
          if (Reflect.has(defOption, k)) {
            let type = Object.prototype.toString.call(v)
            type = type.split(' ')[1].split(']')[0]
            switch (type) {
              case 'Object':
                let defType = Object.prototype.toString.call(defOption[k])
                defType = defType.split(' ')[1].split(']')[0]
                if (defType === 'Object') {
                  this.mergeOption(defOption[k], v)
                } else {
                  defOption[k] = v
                }
                break
              default:
                defOption[k] = v
                break
            }
          } else {
            defOption[k] = v
          }
        }
      },
    },
  }
  </script>
  
  <style lang="scss" scoped></style>
  